# -*- coding: utf-8 -*-

"""
负责全部的操作流程，包括新建，打开，保存，另存为，查找，替换，编码，解码，统计
操作，处理与用户的交互，是程序的主窗体。
"""

from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import QMainWindow, QApplication
from PyQt4.QtCore import pyqtSignature

from Ui_mainForm import Ui_MainWindow
from ReplaceDialog import ReplaceDialog
from Huffman import HuffmanTree
from DrawTree import Dialog as DrawDialog
from Statistic import Statistic

class MainWindow(QMainWindow, Ui_MainWindow):
    """
    主窗口类，负责主要操作流程
    """
    
    def __init__(self):
        """
        加载UI，初始化信息。
        """
        QMainWindow.__init__(self)
        self.setupUi(self)
        
        self.findText = ""

        self.textEdit.document().contentsChanged.connect(self.documentWasModified)
        self.actionExit.triggered.connect(self.close)
        self.setCurrentFileName("")

        self.statusBar.showMessage(QApplication.translate("MainWindow", "Ready"))
    
        self.actionEncode.setEnabled(True)
        self.actionDecode.setEnabled(False)
    
    def documentWasModified(self):
        """
        文本框修改事件处理函数。触发事件后，更新窗体为修改状态，标题栏显示*号。
        """
        self.setWindowModified(self.textEdit.document().isModified())
    
    def setCurrentFileName(self, fileName):
        """
        设置当前文件名
        """
        self.curFileName = fileName
        if fileName == "":
            shownName = QApplication.translate("MainWindow", "untitled.txt")
        else:
            shownName = fileName
        
        self.setWindowTitle(unicode(QApplication.translate("MainWindow", "%s[*] - Application")) % (shownName,))
        self.textEdit.document().setModified(False)
        self.setWindowModified(False)
    
    def new(self):
        """
        新建一个文件
        """
        self.textEdit.clear()
        self.setCurrentFileName("")
        self.textEdit.document().setModified(False)
        self.setWindowModified(False)
        
    def open(self):
        """
        打开一个文件
        """
        self.textEdit.document().setModified(False)
        self.setWindowModified(False)
        
        filename = QtGui.QFileDialog.getOpenFileName(self, QApplication.translate("MainWindow" , "Open file"), filter="Text files (*.txt)")
            
        if filename:
            file = QtCore.QFile(filename)
            file.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text)
            inf = QtCore.QTextStream(file)
            self.textEdit.setPlainText(inf.readAll())
            
            self.setCurrentFileName(filename)

    def save(self):
        """
        保存文件
        """
        if self.textEdit.document().isModified:
            if self.curFileName == "":
                fileName = QtGui.QFileDialog.getSaveFileName(self)
            else:
                fileName = self.curFileName
                
            if fileName:
                file = QtCore.QFile(fileName)
                file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text)
                outf = QtCore.QTextStream(file)
                outf << self.textEdit.toPlainText()
                self.setCurrentFileName(fileName)
                
                self.textEdit.document().setModified(False)
                self.setWindowModified(False)
    
    def maybeSave(self):
        """
        判断当前文件是否处于编辑状态，提示是否保存文件
        """
        if self.textEdit.document().isModified():
            ret = QtGui.QMessageBox.warning(
                        self,
                        QApplication.translate("MainWindow" , "Waring"),
                        QApplication.translate("MainWindow",
                            "The document has been modified.\nDo you want to save your changes?",
                        ),
                        QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel
                    )
            if ret == QtGui.QMessageBox.Save:
                return self.save()
            elif ret == QtGui.QMessageBox.Cancel:
                return False
        return True

    def closeEvent(self, event):
        """
        重写关闭窗体事件处理函数
        """
        if self.maybeSave():
            event.accept()
        else:
            event.ignore()
    
    @pyqtSignature("")
    def on_actionNew_triggered(self):
        """
        新建文件
        """
        if self.maybeSave():
            self.new()
    
    @pyqtSignature("")
    def on_actionOpen_triggered(self):
        """
        打开文件
        """
        if self.maybeSave():
            self.open()
    
    @pyqtSignature("")
    def on_actionSave_triggered(self):
        """
        保存文件
        """
        self.save()
    
    @pyqtSignature("")
    def on_actionSave_As_triggered(self):
        """
        文件另存为
        """
        fileName = QtGui.QFileDialog.getSaveFileName(self)
        if fileName:
            file = QtCore.QFile(fileName)
            file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text)
            outf = QtCore.QTextStream(file)
            outf << self.textEdit.toPlainText()
            self.setCurrentFileName(fileName)
    
    @pyqtSignature("")
    def on_actionFind_triggered(self):
        """
        查找
        """
        text, ok = QtGui.QInputDialog.getText(
                            self,
                            "QInputDialog.getText()",
                            QApplication.translate("MainWindow" , "Find:", None),
                            QtGui.QLineEdit.Normal,
                            # 设置查找对话框查找文本框文本默认为当前选中文本
                            self.textEdit.textCursor().selectedText()
                        )
        if ok:
            self.findText = text
            if self.textEdit.find(text):              
                pass
            else:
                QtGui.QMessageBox.about(
                        self,
                        QApplication.translate("MainWindow" , "Find not"),
                        QApplication.translate("MainWindow" , "Found nothing")
                    )

    def _show_find_no_dialog(self):
        """显示没有找到对话框"""
        QtGui.QMessageBox.about(
            self,
            QApplication.translate("MainWindow" , "Find not"),
            QApplication.translate("MainWindow" , "Found nothing")
        )
        
    @pyqtSignature("")
    def on_actionFind_Next_triggered(self):
        """查找下一个才操作"""
        if not self.textEdit.find(self.findText):
            self._show_find_no_dialog()

    @pyqtSignature("")
    def on_actionFind_Previous_triggered(self):
        """查找上一个操作"""
        if not self.textEdit.find(self.findText, QtGui.QTextDocument.FindBackward):
            self._show_find_no_dialog()

    @pyqtSignature("")
    def on_actionReplace_triggered(self):
        """替换操作"""
        dialog = ReplaceDialog()
        # 设置替换对话框查找文本框文本默认为当前选中文本
        dialog.txt_find.setText(self.textEdit.textCursor().selectedText())
        dialog.exec_()
        
        if dialog.ok:
            # 判断是否执行全部替换操作
            if dialog.cb_ReplaceAll.checkState() == 2:
                count = 0
                while True:
                    prePosition = 0
                    textCur = self.textEdit.document().find(dialog.ori, prePosition)
                    if textCur.position() == -1:
                        break
                    textCur.insertText(dialog.new)
                    self.textEdit.setTextCursor(textCur)
                    prePosition = textCur.position()
                    count += 1
                
                QtGui.QMessageBox.about(self,
                                        QApplication.translate("MainWindow" , "info"),
                                        unicode(QApplication.translate("MainWindow" , 'replaces %s')) % (count, ))
            else:
                self.textEdit.find(dialog.ori)
                tc = self.textEdit.textCursor()
                tc.insertText(dialog.new)
                self.textEdit.setTextCursor(tc)
        
    @pyqtSignature("")
    def on_actionAbout_triggered(self):
        """关于"""
        QtGui.QMessageBox.about(
            self,
            QApplication.translate("MainWindow" , "About"),
            QApplication.translate("MainWindow" , "Just another course design.")
        )
    
    @pyqtSignature("")
    def on_actionEncode_triggered(self):
        """哈夫曼编码"""
        # 哈夫曼编码
        # TODO: 判断文本是否更改，或者是否更换文件。来决定是否重新生成对象。
        txt = str(self.textEdit.toPlainText())
        self.huffman_tree = HuffmanTree(txt)
        encodeString = self.huffman_tree.encode()
        self.textEdit.setPlainText(encodeString)
        
        # 显示哈夫曼树
        trees = self.huffman_tree.tree
        self.dialog = DrawDialog(trees)
        self.dialog.show()
        
        self.actionDecode.setEnabled(True)
        self.actionEncode.setEnabled(False)
    
    @pyqtSignature("")
    def on_actionDecode_triggered(self):
        """哈夫曼解码"""
        decodeString = self.huffman_tree.decode()
        if decodeString is not None:
            self.textEdit.setPlainText(decodeString)
        
        self.actionEncode.setEnabled(True)
        self.actionDecode.setEnabled(False)
    
    @pyqtSignature("")
    def on_actionStatistic_triggered(self):
        """统计"""    
        data = str(self.textEdit.toPlainText())
        statistic = Statistic()
        statistic.start(data)
        statistic.show_table_widget(self)

    @pyqtSignature("")
    def on_actionStatistic_All_triggered(self):
        """打开多个文件，进行统计单词个数"""
        fileNames = QtGui.QFileDialog.getOpenFileNames(self,
                                                       QApplication.translate("MainWindow" , "Open files",),
                                                       filter="Text files (*.txt)")
        if len(fileNames) is 0:
            return
        
        data = ''
        for fileName in fileNames:
            file = QtCore.QFile(fileName)
            file.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text)
            inf = QtCore.QTextStream(file)
            data += inf.readAll()
        data = str(data)
        statistic = Statistic()
        statistic.start(data)
        statistic.show_table_widget(self)
        
    def retranslate(self, language):
        """重新加载语言"""
        self.apptranslate = QtCore.QTranslator()
        self.apptranslate.load('translate/%s' % (language,))
        QtGui.qApp.installTranslator(self.apptranslate)
        self.retranslateUi(self)    
    
    @pyqtSignature("")
    def on_actionEnglish_triggered(self):
        self.retranslate('dscd_en_US.qm')
        
    @pyqtSignature("")
    def on_actionChinese_Simple_triggered(self):
        self.retranslate('dscd_zh_CN.GB2312.qm')


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)    
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())
